/*

*/

#pragma once

#include "RpcRouter.hpp"
#include "RpcRegistry.hpp"
#include "../Common/Dispatcher.hpp"
#include "../Client/RpcClient.hpp"
#include "RpcTopic.hpp"

namespace RpcModule
{
    namespace ServerModule
    {
        // 注册中心服务端实现
        class RegistryServer
        {
        public:
            using ptr = std::shared_ptr<RegistryServer>;
            // 需要给出服务器监听的端口
            RegistryServer(int port)
                : _pd_manager(std::make_shared<ProviderDiscoverManager>()),
                  _dispatcher(std::make_shared<Dispatcher>())
            {
                // 1. 当请求到来时，服务端应该怎么做
                // 只能受到服务注册/服务发现请求
                auto OnRequest = std::bind(&ProviderDiscoverManager::OnServiceRequest, _pd_manager.get(),
                                           std::placeholders::_1, std::placeholders::_2);
                _dispatcher->RegisterHandler<ServiceRequest>(MType::REQ_SERVICE, OnRequest);
                // 2. 当服务端有消息到来，应该怎么做
                auto OnMessage = std::bind(&Dispatcher::OnMessage, _dispatcher.get(),
                                           std::placeholders::_1, std::placeholders::_2);
                _server = MuduoServerFactory::CreateMuduoServer(port);
                _server->SetMessageCallBack(OnMessage);
                // 3. 当客户端有连接关闭时，需要进行服务下线，以及服务下线的通知
                auto OnUnConnection = std::bind(&RegistryServer::OnConnShutDown, this, std::placeholders::_1);
                _server->SetCloseCallBack(OnUnConnection);
            }
            // 向外提供服务器运行的接口
            void Start()
            {
                _server->Start();
            }

        private:
            void OnConnShutDown(const BaseConnection::ptr &conn)
            {
                _pd_manager->OnConnShutDown(conn);
            }

        private:
            ProviderDiscoverManager::ptr _pd_manager;
            BaseServer::ptr _server;
            Dispatcher::ptr _dispatcher;
        };

        // Rpc服务端
        class RpcServer
        {
        public:
            using ptr = std::shared_ptr<RpcServer>;
            // access_addr -- 监听的端口
            // registry_server_addr -- 如果要进行服务注册，需要传入注册中心的地址
            RpcServer(const Address &access_addr, bool enableregistry = false,
                      const Address &registry_server_addr = Address())
                : _enable_registry(enableregistry),
                  _access_addr(access_addr),
                  _dispatcher(std::make_shared<Dispatcher>()),
                  _router(std::make_shared<RpcRouter>())
            {
                if (_enable_registry == true)
                {
                    // 如果要进行服务注册，那么就初始化服务注册客户端
                    _registry_client = std::make_shared<ClientModule::RegisterClient>(
                        registry_server_addr.first, registry_server_addr.second);
                }
                // 1. 设置Rpc请求的回调函数
                auto OnRequest = std::bind(&RpcRouter::OnRpcRequest, _router.get(),
                                           std::placeholders::_1, std::placeholders::_2);
                _dispatcher->RegisterHandler<RpcRequest>(MType::REQ_RPC, OnRequest);
                // 2. 设置当消息到来时的回调函数
                auto OnMessage = std::bind(&Dispatcher::OnMessage, _dispatcher.get(),
                                           std::placeholders::_1, std::placeholders::_2);
                _server = MuduoServerFactory::CreateMuduoServer(access_addr.second);
                _server->SetMessageCallBack(OnMessage);
            }

            // 为用户提供进行服务注册的接口
            void RegisterMethod(const ServiceDescribe::ptr &describe)
            {
                if (_enable_registry == true)
                {
                    LOGDEBUG("服务端向服务中心进行服务注册方法%s", describe->GetMethodName().c_str());
                    _registry_client->RegistryMethod(describe->GetMethodName(), _access_addr);
                }
                // 都需要对服务提供者进行管理
                _router->RegisterMethod(describe);
            }

            void Start()
            {
                _server->Start();
            }

        private:
            bool _enable_registry; // 是否进行服务注册
            Address _access_addr;
            ClientModule::RegisterClient::ptr _registry_client;
            Dispatcher::ptr _dispatcher;
            RpcRouter::ptr _router;
            BaseServer::ptr _server;
        };

        // Topic服务端
        class TopicServer
        {
        public:
            using ptr = std::shared_ptr<TopicServer>;
            TopicServer(int port)
                : _topic_manager(std::make_shared<TopicManager>()),
                  _dispatcher(std::make_shared<Dispatcher>())
            {
                // 1. 注册请求到来时的回调函数
                auto OnRequest = std::bind(&TopicManager::OnTopicRequest, _topic_manager.get(),
                                           std::placeholders::_1, std::placeholders::_2);
                _dispatcher->RegisterHandler<TopicRequest>(MType::REQ_TOPIC, OnRequest);
                // 2. 注册消息到来时的回调函数
                auto OnMessage = std::bind(&Dispatcher::OnMessage, _dispatcher.get(),
                                           std::placeholders::_1, std::placeholders::_2);
                _server = MuduoServerFactory::CreateMuduoServer(port);
                _server->SetMessageCallBack(OnMessage);
                // 3. 注册连接关闭时的回调函数
                auto OnShutDown = std::bind(&TopicServer::OnConnectionShutDown, this,
                                            std::placeholders::_1);
                _server->SetCloseCallBack(OnShutDown);
            }
            // 服务端启动
            void Start()
            {
                _server->Start();
            }

        private:
            void OnConnectionShutDown(const BaseConnection::ptr &conn)
            {
                _topic_manager->OnShutDown(conn);
            }

        private:
            TopicManager::ptr _topic_manager; // 注册到Dispatcher Topic Request OnMessage
            Dispatcher::ptr _dispatcher;
            BaseServer::ptr _server; // 服务端，用于接收客户端
        };
    }
}